<template>
  <canvas ref="canvas" class="firework-canvas"></canvas>
</template>

<script>
export default {
  name: 'firework',
  data() {
    return {
      ctx: null,
      particles: [],
      rockets: [], // 新增rockets数组存储上升的火箭
      canvasWidth: 0,
      canvasHeight: 0,
      stars: [], // 添加stars数组存储星星
      starCount: 200, // 星星数量
      isShowNumber: true
    }
  },
  mounted() {
    const canvas = this.$refs.canvas
    this.ctx = canvas.getContext('2d')
    this.canvasWidth = canvas.width = window.innerWidth
    this.canvasHeight = canvas.height = window.innerHeight

    // 定期创建新的火箭
    setInterval(() => {
      // 随机生成1-3个火箭
      const rocketCount = Math.floor(Math.random() * 2) + 1
      for (let i = 0; i < rocketCount; i++) {
        // 为每个火箭添加少许延迟，使发射时间错开
        setTimeout(() => {
          this.createRocket()
        }, Math.random() * 1000) // 0-500ms的随机延迟
      }
    }, 1000)

    // 初始化星空
    this.createStars()

    this.animate()
  },
  methods: {
    // 圆形烟花（原有的样式）
    createCircleFirework(x, y) {
      const particleCount = 50
      const color = `hsl(${Math.random() * 360}, 50%, 50%)`

      for(let i = 0; i < particleCount; i++) {
        const angle = (Math.PI * 2 * i) / particleCount
        const velocity = 2 + Math.random() * 2
        this.particles.push({
          x,
          y,
          vx: Math.cos(angle) * velocity,
          vy: Math.sin(angle) * velocity,
          life: 100,
          color
        })
      }
    },
    // 环形烟花
    createRingFirework(x, y) {
      const rings = 3
      const particlesPerRing = 30
      const color = `hsl(${Math.random() * 360}, 50%, 50%)`

      for(let ring = 0; ring < rings; ring++) {
        const velocity = 1 + ring * 1.5
        for(let i = 0; i < particlesPerRing; i++) {
          const angle = (Math.PI * 2 * i) / particlesPerRing
          this.particles.push({
            x,
            y,
            vx: Math.cos(angle) * velocity,
            vy: Math.sin(angle) * velocity,
            life: 100,
            color
          })
        }
      }
    },
    // 心形烟花
    createHeartFirework(x, y) {
      const particleCount = 50
      const color = `hsl(${Math.random() * 360}, 50%, 50%)`

      for(let i = 0; i < particleCount; i++) {
        const angle = (Math.PI * 2 * i) / particleCount
        const velocity = 2 + Math.random() * 2
        // 心形方程
        const heartX = 16 * Math.pow(Math.sin(angle), 3)
        const heartY = 13 * Math.cos(angle) - 5 * Math.cos(2 * angle) - 2 * Math.cos(3 * angle) - Math.cos(4 * angle)

        this.particles.push({
          x,
          y,
          vx: heartX * 0.2,
          vy: -heartY * 0.2,
          life: 100,
          color
        })
      }
    },
    // 添加数字烟花方法
    createNumberFirework(x, y, text) {
      const fontSize = 120  // 增大字体尺寸
      this.ctx.font = `bold ${fontSize}px Arial`

      this.ctx.fillStyle = 'rgba(0, 0, 0, 0)' // 透明填充

      // 获取文本宽度以居中显示
      const textWidth = this.ctx.measureText(text).width
      const startX = x - textWidth / 2

      // 在离屏 canvas 上绘制文字
      const offscreen = document.createElement('canvas')
      const offscreenCtx = offscreen.getContext('2d')
      offscreen.width = textWidth
      offscreen.height = fontSize * 1.5

      offscreenCtx.font = `bold ${fontSize}px Arial`
      offscreenCtx.fillStyle = 'white'
      offscreenCtx.fillText(text, 0, fontSize)

      // 获取像素数据
      const imageData = offscreenCtx.getImageData(0, 0, offscreen.width, offscreen.height)
      const pixels = imageData.data
      const color = `hsl(${Math.random() * 360}, 80%, 60%)`
      const particleGap = 16

      for (let i = 0; i < pixels.length; i += 4 * particleGap) {
        const pixelX = (i / 4) % offscreen.width
        const pixelY = Math.floor((i / 4) / offscreen.width)

        if (pixels[i + 3] > 128 && Math.random() > 0.3) {
          // 缩小初始位置范围，让粒子更靠近目标位置
          const targetX = startX + pixelX
          const targetY = y + pixelY - fontSize
          const spread = 100  // 初始分布范围

          const randomX = targetX + (Math.random() - 0.5) * spread
          const randomY = targetY + (Math.random() - 0.5) * spread

          this.particles.push({
            x: randomX,
            y: randomY,
            originX: targetX,
            originY: targetY,
            vx: 0,
            vy: 0,
            isNumber: true,
            phase: 'gather',
            stayTime: 40,
            fadeTime: 20,
            opacity: 1,
            color: color,
            size: 2.5,
            initialDistance: Math.hypot(randomX - targetX,
              randomY - targetY)
          })
        }
      }
    },
    createStars() {
      for (let i = 0; i < this.starCount; i++) {
        this.stars.push({
          x: Math.random() * this.canvasWidth,
          y: Math.random() * this.canvasHeight,
          size: Math.random() * 2,
          twinkle: Math.random() // 闪烁效果
        })
      }
    },
    drawStars() {
      this.stars.forEach(star => {
        star.twinkle += 0.02
        // 降低整体不透明度范围
        const opacity = (Math.abs(Math.sin(star.twinkle)) * 0.3 + 0.1)

        // 降低星星颜色亮度
        this.ctx.fillStyle = `rgba(180, 180, 180, ${opacity})`
        this.ctx.beginPath()
        this.ctx.arc(star.x, star.y, star.size, 0, Math.PI * 2)
        this.ctx.fill()
      })
    },
    createRocket() {
      // 随机生成火箭的发射位置
      const x = Math.random() * this.canvasWidth
      const rocket = {
        x,
        y: this.canvasHeight,
        targetY: this.canvasHeight * 0.2 + Math.random() * this.canvasHeight * 0.3,
        vy: -15 - Math.random() * 5,
        color: `hsl(${Math.random() * 360}, 50%, 50%)`
      }
      this.rockets.push(rocket)
    },
    createFirework(x, y) {

      // 随机选择烟花类型
      const types = ['circle', 'number', 'ring', 'circle']
      let typeIndex = Math.floor(Math.random() * types.length)

      if (typeIndex == 1 && this.isShowNumber) {
        this.isShowNumber = false;
      } else {
        this.isShowNumber = true
        typeIndex = 0;
      }

      let typeDesc = types[typeIndex]

      switch (typeDesc) {
        case 'circle':
          this.createCircleFirework(x, y)
          break
        case 'heart':
          this.createHeartFirework(x, y)
          break
        case 'number':
          this.createNumberFirework(x, y, '2025')
          break
        case 'ring':
          this.createRingFirework(x, y)
          break
      }
    },
    animate() {
      // 清除画布
      this.ctx.fillStyle = 'rgba(0, 0, 0, 0.2)'
      this.ctx.fillRect(0, 0, this.canvasWidth, this.canvasHeight)

      // 绘制星空
      this.drawStars()

      // 更新和绘制火箭
      this.rockets.forEach((rocket, index) => {
        rocket.y += rocket.vy

        // 绘制火箭
        this.ctx.fillStyle = rocket.color
        this.ctx.beginPath()
        this.ctx.arc(rocket.x, rocket.y, 3, 0, Math.PI * 2)
        this.ctx.fill()

        // 绘制火箭尾迹
        this.ctx.beginPath()
        this.ctx.strokeStyle = rocket.color
        this.ctx.lineWidth = 2
        this.ctx.moveTo(rocket.x, rocket.y)
        this.ctx.lineTo(rocket.x, rocket.y + 10)
        this.ctx.stroke()

        // 当火箭达到目标高度时，创建烟花并移除火箭
        if (rocket.y <= rocket.targetY) {
          this.createFirework(rocket.x, rocket.y)
          this.rockets.splice(index, 1)
        }
      })

      // 更新和绘制粒子
      this.particles.forEach((particle, index) => {
        if (particle.isNumber) {
          switch (particle.phase) {
            case 'gather':
              const dx = particle.originX - particle.x
              const dy = particle.originY - particle.y
              const distance = Math.sqrt(dx * dx + dy * dy)
              const progress = 1 - (distance / particle.initialDistance)

              if (distance < 0.5) {
                particle.x = particle.originX
                particle.y = particle.originY
                particle.vx = 0
                particle.vy = 0
                particle.phase = 'stay'
              } else {
                // 增加加速度使粒子更快聚集
                const acceleration = 0.05 * (1 + progress)
                particle.vx += dx * acceleration
                particle.vy += dy * acceleration
                // 减小阻力使运动更快
                particle.vx *= 0.88
                particle.vy *= 0.88
              }
              break

            case 'stay':
              particle.stayTime--
              // 减少抖动幅度
              if (particle.stayTime > 0) {
                particle.x += (Math.random() - 0.5) * 0.2
                particle.y += (Math.random() - 0.5) * 0.2
              }
              if (particle.stayTime <= 0) {
                particle.phase = 'fade'
              }
              break

            case 'fade':
              particle.fadeTime--
              particle.opacity = particle.fadeTime / 20  // 更新淡出计算
              // 加快上升速度
              particle.y -= 0.4
              if (particle.fadeTime <= 0) {
                this.particles.splice(index, 1)
                return
              }
              break
          }
        } else {
          // 普通烟花的逻辑
          particle.vy += 0.05
        }

        particle.x += particle.vx
        particle.y += particle.vy

        // 优化粒子绘制
        const opacity = particle.opacity !== undefined ? particle.opacity : 1
        this.ctx.fillStyle = particle.isNumber
          ? `rgba(${particle.color.match(/\d+/g).slice(0,3).join(',')},${opacity})`
          : particle.color
        this.ctx.beginPath()
        // 使用粒子自身的大小
        const size = particle.size || 2
        this.ctx.arc(particle.x, particle.y, size, 0, Math.PI * 2)
        this.ctx.fill()

        // 为数字粒子添加发光效果
        if (particle.isNumber && opacity > 0.2) {
          this.ctx.globalAlpha = opacity * 0.4
          this.ctx.shadowBlur = 5
          this.ctx.shadowColor = particle.color
          this.ctx.fill()
          this.ctx.globalAlpha = 1
          this.ctx.shadowBlur = 0
        }

        if (!particle.isNumber && particle.life <= 0) {
          this.particles.splice(index, 1)
        }
      })

      requestAnimationFrame(this.animate)
    }
  }
}
</script>

<style scoped>
.firework-canvas {
  position: fixed;
  top: 0;
  left: 0;
  background: black;
}
</style>
